package com.cn.admin.service.impl;

import com.cn.admin.dao.RoleMapper;
import com.cn.admin.dao.UserMapper;
import com.cn.admin.datasource.DataSources;
import com.cn.admin.datasource.RoutingDataSource;
import com.cn.admin.entity.*;
import com.cn.admin.exception.CustomException;
import com.cn.admin.service.UserService;
import com.cn.admin.utils.BaseServiceImpl;
import com.cn.admin.utils.JwtUtils;
import com.cn.admin.vo.ResponseObject;
import com.cn.admin.vo.ResponseUserToken;
import com.cn.admin.vo.ResultCode;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class UserServiceImpl extends BaseServiceImpl<User, UserQuery,Long> implements UserService   {

    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtUtils jwtTokenUtil;






    @Override
    public User selectByPrimaryKey1(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    @RoutingDataSource(value = DataSources.SLAVE_DB)
    public User selectByPrimaryKey2(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public User selectByUsername(String username) {
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(String.format("用户不存在", username));
        }
        /*RoleQuery roleQuery=new RoleQuery();
        roleQuery.createCriteria().and
        Role role = roleMapper.selectByExample()
        user.setRole(role);*/
        return user;
    }


    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    public UserServiceImpl(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }


    @Override
    public  ResponseUserToken login(String username,String password){

        //用户验证
        Authentication authentication = authenticate(username, password);
        //存储认证信息
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //生成token
        UserDetail userDetail = (UserDetail) authentication.getPrincipal();
//        User user = (User) userDetailsService.loadUserByUsername(username);
        String token = jwtTokenUtil.generateAccessToken(userDetail);
        //存储token
        jwtTokenUtil.putToken(username, token);

        return new ResponseUserToken(token, userDetail);

    }


    private Authentication authenticate(String username, String password) {
        try {
            //该方法会去调用userDetailsService.loadUserByUsername()去验证用户名和密码，如果正确，则存储该用户名密码到“security 的 context中”
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException | BadCredentialsException e) {
            throw new CustomException(ResponseObject.fail(20000,e.getMessage().toString()));
        }
    }



    @Override
    public int register(User user) {
        String username = user.getUsername();
        if(userMapper.selectByUsername(username)!=null) {
            throw new CustomException(ResponseObject.fail(ResultCode.BAD_REQUEST.getCode(), "用户已存在"));
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = user.getPassword();
        user.setPassword(encoder.encode(rawPassword));
        int insert = userMapper.insert(user);

        return insert;
    }
}
